#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include "typesprimitifs.h" 
#include "produit.h" 
#include "test_produit.h" 
#include "categorie.h"   

/**  
 * Nombres de test reussies.
 */
static ENTIER_POSITIF ok_tests_produit = 0;
/**  
 * Nombre de test ayant echoue.
 */
static ENTIER_POSITIF ko_tests_produit = 0;

void set_up_tests_produit() {
    printf("-------- DEBUT TEST: PRODUIT --------\n");
}

void tester_creer_produit(CHAINE nom, ENTIER_POSITIF quantite_dispo,
        DOUBLE prix_un, CATEGORIE categorie) {
    /*Creation d'un pointeur sur produit*/
    POINTEUR_PRODUIT pp = creer_produit(nom, quantite_dispo, prix_un,
            categorie);
    /*Verifier que le pointeur est non null.*/
    if (pp != NULL) {
        ok_tests_produit++;
        printf("PASSED: tester_creer_produit.\n");
    } else {
        ko_tests_produit++;
        printf("FAILED: tester_creer_produit.\n");
    }
}

void tester_liberer_produit(POINTEUR_PRODUIT pp) {
    liberer_produit(pp);
    if (pp == NULL) {
        ok_tests_produit++;
        printf("PASSED: tester_liberer_produit.\n");
    } else {
        ko_tests_produit++;
        printf("FAILED: tester_liberer_produit.\n");
    }
}

void tester_afficher_produit(POINTEUR_PRODUIT pp) {
    printf("----- Test d'affichage du produit ------\n");
    if (pp != NULL) {
        afficher_produit(pp);
        ok_tests_produit++;
        printf("PASSED: tester_afficher_produit.\n");
        free(pp);
    } else {
        ko_tests_produit++;
        printf("FAILED: tester_afficher_produit.\n");
    }
}

BOOLEEN tester_augmenter_quantite_disponible(POINTEUR_PRODUIT pp,
                                            ENTIER_POSITIF quantite) {
    BOOLEEN resultat;
    ENTIER_POSITIF quantite_initial;

    if (pp != NULL) {
        quantite_initial = pp->quantite_disponible;
        resultat = augmenter_quantite_disponible(quantite, pp);
        if (((pp->quantite_disponible - quantite) == quantite_initial) && resultat) {
            ok_tests_produit++;
            printf("PASSED: tester_augmenter_quantite_disponible.\n");

        } else {
            ko_tests_produit++;
            printf("FAILED: tester_augmenter_quantite_disponible.\n");
        }
        free(pp);
    } else {
        printf("NOT RUN: tester_changer_prix_unitaire.\n");
    }
    return resultat;
}

BOOLEEN tester_reduire_quantite_disponible(POINTEUR_PRODUIT pp,
                                            ENTIER_POSITIF quantite) {
    BOOLEEN resultat;
    ENTIER_POSITIF quantite_initial;

    if (pp != NULL) {
        quantite_initial = pp->quantite_disponible;
        resultat = reduire_quantite_disponible(quantite, pp);
        if (((pp->quantite_disponible + quantite) == quantite_initial) && resultat) {
            ok_tests_produit++;
            printf("PASSED: tester_reduire_quantite_disponible.\n");

        } else {
            ko_tests_produit++;
            printf("FAILED: tester_reduire_quantite_disponible.\n");
        }
        free(pp);
    } else {
        printf("NOT RUN: tester_changer_prix_unitaire.\n");
    }
    return resultat;
}

BOOLEEN tester_changer_prix_unitaire(DOUBLE prix_un, POINTEUR_PRODUIT pp) {
    BOOLEEN resultat;

    if (pp != NULL) {
        resultat = changer_prix_unitaire(prix_un, pp);
        if (prix_un == pp->prix_u && pp->prix_u > 0 && resultat) {
            ok_tests_produit++;
            printf("PASSED: tester_changer_prix_unitaire.\n");
        } else {
            ko_tests_produit++;
            printf("FAILED: tester_changer_prix_unitaire.\n");
        }
        free(pp);
    } else {
        printf("NOT RUN: tester_changer_prix_unitaire.\n");
    }
    return resultat;
}

void tear_down_tests_produit() {
    printf("------ STATS TESTS PRODUIT -----\n");
    printf("Tests reussis: %d\n", ok_tests_produit);
    printf("Tests echoues : %d\n", ko_tests_produit);
    printf("--------------------------------\n");
    printf("FIN TEST: PRODUIT\n");
}

void tests_produit(POINTEUR_PRODUIT pp, CHAINE nom,
        ENTIER_POSITIF quantite_dispo,
        ENTIER_POSITIF quantite,
        DOUBLE prix_un, CATEGORIE categorie) {
    set_up_tests_produit();
    tester_creer_produit(nom, quantite_dispo, prix_un, categorie);
    tester_liberer_produit(pp);
    tester_afficher_produit(pp);
    tester_augmenter_quantite_disponible(pp, quantite);
    tester_reduire_quantite_disponible(pp, quantite);
    tester_changer_prix_unitaire(prix_un, pp);
    tear_down_tests_produit();
}
